<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
lang="en" xml:lang="en">
<head>
<title>Autoproject</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="generator" content="Org-mode"/>
<meta name="generated" content="2009/11/30 23:07:55"/>
<meta name="author" content="Peter von Etter"/>
<style type="text/css">
  html {
	font-family: sans-serif;
	font-size: 12pt;
  }
  body {margin-left: 5em; margin-right: 5em} 
 .title { text-align: center; }
  .todo  { color: red; }
  .done { color: green; }
  .timestamp { color: grey }
  .timestamp-kwd { color: CadetBlue }
  .tag { background-color:lightblue; font-weight:normal }
  .target { background-color: lavender; }
  pre {
	border: 1pt solid #AEBDCC;
	background-color: #F3F5F7;
	padding: 5pt;
	font-family: courier, monospace;
  }
  table { border-collapse: collapse; }
  td, th {
	vertical-align: top;
	<!--border: 1pt solid #ADB9CC;-->
  }
</style>
</head><body>
<h1 class="title">Autoproject</h1>
<h2>Table of Contents</h2>
<ul>
<li><a href="#sec-1">1 Introduction</a></li>
<li><a href="#sec-2">2 Obtaining</a></li>
<li><a href="#sec-3">3 Installation</a>
<ul>
<li><a href="#sec-4">3.1 General</a></li>
<li><a href="#sec-5">3.2 Notes</a></li>
</ul>
</li>
<li><a href="#sec-6">4 Usage</a>
<ul>
<li><a href="#sec-7">4.1 AP-Makefile</a>
<ul>
<li><a href="#sec-8">4.1.1 Generating a Makefile  </a></li>
<li><a href="#sec-9">4.1.2 Targets supported</a></li>
</ul>
</li>
<li><a href="#sec-10">4.2 AP-Autoasdf</a></li>
<li><a href="#sec-11">4.3 AP-Pkg</a>
<ul>
<li><a href="#sec-12">4.3.1 Alias</a></li>
</ul>
</li>
<li><a href="#sec-13">4.4 AP-Crud</a></li>
</ul>
</li>
<li><a href="#sec-14">5 Package Interface</a>
<ul>
<li><a href="#sec-15">5.1 AUTOPROJECT  </a>
<ul>
<li><a href="#sec-16">5.1.1 MAKE-MAKEFILE-FOR-SYSTEM</a></li>
<li><a href="#sec-17">5.1.2 MAKE-AUTOASDF-SHELLSCRIPT</a></li>
</ul>
</li>
<li><a href="#sec-18">5.2 AUTOPROJECT.PKG</a>
<ul>
<li><a href="#sec-19">5.2.1 ALIAS</a></li>
</ul>
</li>
<li><a href="#sec-20">5.3 AUTOPROJECT.CRUD</a>
<ul>
<li><a href="#sec-21">5.3.1 WRITE-CRUD-FORMS-TO-FILE</a></li>
</ul></li>
</ul>
</li>
<li><a href="#sec-22">6 Supported implementations</a>
<ul>
<li><a href="#sec-23">6.1 Porting to other implementations</a></li>
</ul>
</li>
</ul>

<h2><a name="sec-1">1 Introduction</a></h2>


<p>
Autoproject is a library intended to aid in building Common Lisp
software.  Currently it consists of five modules:
</p>
<ul>
<li>
ap-makefile

<p>
Generates makefiles from asdf system definitions
</p>
</li>
<li>
ap-autoasdf

<p>
Generates a shell script called "autoasdf" that will build asdf
systems.
</p>
</li>
<li>
ap-pkg

<p>
Package related utilities.  Currently exports a single symbol, ALIAS.
</p>
</li>
<li>
ap-crud

<p>
A tool to generate class definitions corresponding to a database
schema.
</p>
</li>
<li>
ap-util

<p>
A collection of utilities used by the other modules.  Also defines
some useful asdf related functions.
</p>

</li>
</ul>
<h2><a name="sec-2">2 Obtaining</a></h2>


<p>
Autoproject is available at <a href="http://code.google.com/p/autoproject">http://code.google.com/p/autoproject</a>
</p>

<h2><a name="sec-3">3 Installation</a></h2>



<h3><a name="sec-4">3.1 General</a></h3>


<ol>
<li>
Symlink autoproject.asd to your systems directory.

</li>
<li>
Optional: Symlink the scripts you like from the scripts directory
to your ~/bin directory.

</li>
</ol>

<h3><a name="sec-5">3.2 Notes</a></h3>


<p>
The module ap-pkg can be loaded separately using autoproject.pkg.asd.
</p>


<h2><a name="sec-6">4 Usage</a></h2>




<h3><a name="sec-7">4.1 AP-Makefile</a></h3>



<h4><a name="sec-8">4.1.1 Generating a Makefile  </a></h4>


<p>
To generate a makefile, make sure the asd file of your system has
been symlinked to one of your systems directories.  Then simply run
the script
</p>
<p>
<pre>
 make-makefile MY-SYSTEM
</pre>
</p>
<p>
Alternatively, one can call
</p>
<p>
<pre>
 (require :autoproject)
 (autoproject:make-makefile-for-system MY-SYSTEM)
</pre>
</p>
<p>
from lisp.  MY-SYSTEM should be a string or a symbol.
</p>


<h4><a name="sec-9">4.1.2 Targets supported</a></h4>


<p>
The generated makefile supports the following targets:
</p>
<ul>
<li>
build

<p>
Creates a base core containing the dependencies of a system, then
builds the system using that core.  Subsequent invocations of make
will be quicker because the base core already contains the
dependencies.
</p>
</li>
<li>
rebuild

<p>
Deletes all fasl files in a system, then rebuilds it using the
base core.
</p>
</li>
<li>
build-inc

<p>
Builds a system in such a way that every dependency is built with
only its dependencies loaded.  This is done by invoking lisp
sub-processes for each system in the dependency tree starting from
the leaves.
</p>
</li>
<li>
rebuild-inc

<p>
Much like build-inc, except fasl files are deleted before
compiling systems.
</p>
</li>
<li>
baseless

<p>
Builds a system without using a base core.
</p>
</li>
<li>
core 

<p>
Builds the system, then saves the core.  The core will be named
"my-app.core" where "my-app" is the name of the system being built.
</p>
</li>
<li>
clean

<p>
Deletes any cores and fasl files associated with a system.
</p>
</li>
<li>
slime

<p>
Builds the system, then starts up a swank server.
</p>

</li>
</ul>
<h3><a name="sec-10">4.2 AP-Autoasdf</a></h3>


<p>
The autoasdf shell script offers the same targets as the makefile.
Which one to use is mostly a matter of taste.
</p>
<p>
Example usage:
</p>
<p>
<pre>
 autoasdf build my-system
</pre>
</p>
<p>
Run the script without arguments to see the supported targets.
</p>


<h3><a name="sec-11">4.3 AP-Pkg</a></h3>



<h4><a name="sec-12">4.3.1 Alias</a></h4>


<p>
Common Lisp doesn't specify package-local nicknames.  This can lead to
very long package names in order to ensure uniqueness.  This isn't
usually a problem since packages can be 'used'.  But 'using' packages
can sometimes become problematic, especially if the number of exported
symbols in the used packages is very large.
</p>
<p>
The function AUTOPROJECT.PKG:ALIAS provides a straightforward facility
for renaming packages temporarily as if they were local to a system or
package.  Any nicknames except the standard package names can be
chosen, as package name conflicts are handled by a 'shadowing'
mechanism. 
</p>
<p>
Example usage:
</p>
<p>
In <b>packages.lisp</b>:
</p>
<p>
<pre>
 (defpackage :my-package
   (:use :cl)
   (:export #:my-function))
 
 (pkg:alias '((:com.really.long.package.util :util)
              (:com.another.package.foo :foo)
              (:com.a.third.package.bar :bar)))
</pre>
</p>
<p>
In <b>code.lisp</b>:
</p>
<p>
<pre>
 (defun my-function (x)
   (let ((q (util:prepare-for-xuul x)))
     (foo:handle-xuul (bar:make-xuul q))))
 
 ;; Be nice to others, reset nicknames
 (pkg:alias) 
</pre>
</p>
<p>
Note that it is a good idea to reset the nicknames after the system
has been compiled or loaded.  This can be achieved by calling
PKG:ALIAS with no arguments in the last file of the system (although
any call to ALIAS will reset the nicknames). 
</p>


<h3><a name="sec-13">4.4 AP-Crud</a></h3>


<p>
AP-Crud provides tools to automatically generate class definitions
when given a database schema.  It is intended to make dealing with
databases less tedious.  The only requirement is that each table
should have a primary integer key called <em>id</em>.  Here is a
brief example of how to use the module:
</p>
<p>
Suppose we have a database with the following layout:
</p>
<p>
customer
</p><ul>
<li>
id
</li>
<li>
name
</li>
<li>
address
</li>
<li>
email

</li>
</ul>product
<ul>
<li>
id
</li>
<li>
name
</li>
<li>
description
</li>
<li>
price

</li>
</ul>order
<ul>
<li>
id
</li>
<li>
customer_id
</li>
<li>
order_contents_id

</li>
</ul>order_contents
<ul>
<li>
id
</li>
<li>
order_id
</li>
<li>
product_id

</li>
</ul>The crud module would generate approximately the following code:

<p>
<pre>
 (defclass customer ()
   (id :accessor get-id :initarg :id)
   (name :accessor get-name :initarg :name)
   (address :accessor get-address :initarg :address)
   (email :accessor get-email :initarg :email))
 
 (defclass product ()
   ((id :accessor get-id :initarg :id)
    (name :accessor get-name :initarg :name)
    (description :accessor get-description :initarg :description)
    (price :accessor get-price :initarg :price)))
 
 (defclass order ()
   ((id :accessor get-id :initarg :id)
    (customer-id :accessor get-customer-id :initarg :customer-id)
    (order-contents-id :accessor get-order-contents-id 
                       :initarg :order-contents-id)))
 
 (defclass order-contents ()
   ((id :accessor get-id :initarg :id)
    (order-id :accessor get-order-id :initarg :order-id)
    (product-id :accessor get-product-id :initarg :product-id)))
</pre>
</p>
<p>
The above code has been simplified for illustrative purposes.
</p>
<p>
The generated classes can be used to manipulate the contents of the
database using the functions provided by the crud module, namely
Create, Read, Update and Delete, as one would expect.  Additionally a
"match" operation is provided that queries the database using partial
instances.
</p>
<p>
In our example, adding a new customer can be done by creating a
customer instance and saving it to the database:
</p>
<p>
<pre>
 (let* ((name "Homer Simpson")
        (address "742 Evergreen Terrace, Springfield")
        (customer (make-instance 'customer :name name
                                           :address address)))
    (crud-create-from-instance *crud* customer))
</pre>
</p>
<p>
Here *crud* is assumed to be bound to a crud instance for the schema
shown above.
</p>
<p>
The database can be queried with the match operation:
</p>
<p>
<pre>
 (let ((customer (make-instance 'customer :name "Homer Simpson")))
    (crud-match *crud* customer))
</pre>
</p>
<p>
This would return a list of customer instances that have the name
"Homer Simpson".
</p>
<p>
Updating rows can be done by manipulating instance slots and saving
the instance:
</p>
<p>
<pre>
 (let* ((customer (make-instance 'customer :name "Homer Simpson")))
        (homer (first (crud-match *crud* customer))))
    (setf (get-email homer) "chunkylover53@aol.com")
    (crud-update-from-instance homer))
</pre>
</p>
<p>
In the previous example, the match operation is only done to get the
id of the row.  If the id of the row is known, then updating is
simpler:
</p>
<p>
<pre>
 (let* ((homer (make-instance 'customer :id 4534)))
    (setf (get-email homer) "chunkylover53@aol.com")
    (crud-update-from-instance homer))
</pre>
</p>

<p>
The file <a href="http://www.cs.helsinki.fi/u/pjetter/autoproject/ap-crud/crud-example.lisp">ap-crud/crud-example.lisp</a> contains more detailed example
code for generating and using cruds.  Until more comprehensive
documentation can be written, the reader is encouraged to explore the
ap-crud directory and the function documentation strings as well as
the automatically generated <a href="http://www.cs.helsinki.fi/u/pjetter/autoproject/doc/index.html">documentation</a>.
</p>


<h2><a name="sec-14">5 Package Interface</a></h2>



<h3><a name="sec-15">5.1 AUTOPROJECT  </a></h3>


<p>
The following symbols are exported by the AUTOPROJECT package:
</p>

<h4><a name="sec-16">5.1.1 MAKE-MAKEFILE-FOR-SYSTEM</a></h4>


<p>
<em>(function)</em>
</p>
<p>
<pre>
 MAKE-MAKEFILE-FOR-SYSTEM SYSTEM
</pre>
</p>
<p>
Creates a makefile for the asdf system SYSTEM in the directory
containing the "asd" file.
</p>

<h4><a name="sec-17">5.1.2 MAKE-AUTOASDF-SHELLSCRIPT</a></h4>


<p>
<em>(function)</em>
</p>
<p>
<pre>
 MAKE-AUTOASDF-SHELLSCRIPT
</pre>
</p>
<p>
Creates the autoasdf shellscript.
</p>

<h3><a name="sec-18">5.2 AUTOPROJECT.PKG</a></h3>


<p>
The following symbols are exported by the AUTOPROJECT.PKG package:
</p>

<h4><a name="sec-19">5.2.1 ALIAS</a></h4>


<p>
<em>(function)</em>
</p>
<p>
<pre>
 ALIAS PACKAGE-NICK-ALIST
</pre>
</p>
<p>
Arranges for packages to have nicknames according to
PACKAGE-NICK-ALIST.  The state of any packages involved in the
renaming process is restored the next time ALIAS is called.
</p>


<h3><a name="sec-20">5.3 AUTOPROJECT.CRUD</a></h3>


<p>
For detailed information, please refer to the function documentation
in the code and the example file "ap-crud/crud-example.lisp".  Also
see the automatically generated <a href="http://www.cs.helsinki.fi/u/pjetter/autoproject/doc/index.html">documentation</a>.
</p>


<h4><a name="sec-21">5.3.1 WRITE-CRUD-FORMS-TO-FILE</a></h4>


<p>
<em>(function)</em>
</p>
<p>
<pre>
 WRITE-CRUD-FORMS-TO-FILE CRUD FILE CLASS-NAME PACKAGE-NAME
</pre>
</p>
<p>
Generates a crud source file named FILE from the database pointed to
by CRUD.  The crud class will be called CLASS-NAME and generated code
will go into the package PACKAGE-NAME.
</p>
<p>
A standard class will be generated for each database table, with slots
corresponding to fields in the table.  Accessors will also be
generated.  It is required that each table contain a primary integer
key field named "id".
</p>
<p>
Instances of the generated classes will be returned, or used as
arguments, by the following functions:
</p>
<ul>
<li>
CRUD-CREATE 
</li>
<li>
CRUD-CREATE-FROM-INSTANCE
</li>
<li>
CRUD-READ
</li>
<li>
CRUD-READ-FROM-INSTANCE
</li>
<li>
CRUD-UPDATE
</li>
<li>
CRUD-UPDATE-FROM-INSTANCE
</li>
<li>
CRUD-DELETE
</li>
<li>
CRUD-DELETE-FROM-INSTANCE
</li>
<li>
CRUD-MATCH


</li>
</ul>
<h2><a name="sec-22">6 Supported implementations</a></h2>


<p>
Currently the following implementations have been tested:
</p>
<ul>
<li>
SBCL 1.0.29 (autoproject)
</li>
<li>
clisp (ap-pkg only)


</li>
</ul>
<h3><a name="sec-23">6.1 Porting to other implementations</a></h3>


<p>
Autoproject should be easily portable to other implementations.
</p>
<p>
In order to port it to another implementation the following is
currently needed:
</p>
<ol>
<li>
Fill in the blanks in ap-makefile/impl.lisp
</li>
<li>
Port the shell scripts in the scripts directory

<p>

<hr/>
</p>
</li>
</ol>
<p class="author"> Author: Peter von Etter
<a href="mailto:peterve@gmail.com">&lt;peterve@gmail.com&gt;</a>
</p>
<p class="date"> Date: 2009/11/30 23:07:55</p>
</body>
</html>
